package com.ebt.m.wiki.view;

import android.annotation.SuppressLint;
import android.content.Context;
import android.graphics.Typeface;
import android.graphics.drawable.ColorDrawable;
import android.os.Build;
import android.text.Spannable;
import android.text.SpannableString;
import android.text.Spanned;
import android.text.style.AbsoluteSizeSpan;
import android.text.style.StyleSpan;
import android.text.style.UnderlineSpan;
import android.util.AttributeSet;
import android.util.Log;
import android.view.Gravity;
import android.view.ScaleGestureDetector;
import android.view.ScaleGestureDetector.OnScaleGestureListener;
import android.view.View;
import android.webkit.JavascriptInterface;
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.widget.LinearLayout;
import android.widget.PopupWindow;
import android.widget.TextView;

import com.ebt.m.R;
import com.ebt.m.commons.utils.Logger;
import com.ebt.m.commons.utils.NetUtils;
import com.ebt.m.data.bean.clause.ExplainContent;
import com.ebt.m.data.entity.ProductBridgeObj;
import com.ebt.m.data.middle.EBTFileOption;
import com.ebt.m.data.middle.EBTGetAdviceInfo;
import com.ebt.m.utils.ConfigData;
import com.ebt.m.utils.UIHelper;
import com.ebt.m.view.NestedWebView;

import org.json.JSONException;
import org.json.JSONObject;
import org.w3c.dom.DOMException;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

/**
 * 险种条款WebView
 *
 * @author Michael.li
 */
public class ClauseWebView extends NestedWebView implements OnScaleGestureListener {

    private static final String TAG = "ClauseWebView";
    private List<ExplainContent> mExplainList;

    public PopupWindow getmPopupWindow() {
        return mPopupWindow;
    }

    private PopupWindow mPopupWindow;
    private TextView mTextView;
    /**
     * 缩小
     */
    private boolean mZoomOut;
    private float mTempSpan;

    private String mClauseXMLPath;

    public ClauseWebView(Context context) {
        this(context, null);
    }

    public ClauseWebView(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public ClauseWebView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        if (isInEditMode()) {
            return;
        }

        initSettings();
    }


    @Override
    public boolean onScale(ScaleGestureDetector detector) {
        return true;
    }

    @Override
    public boolean onScaleBegin(ScaleGestureDetector detector) {
        mTempSpan = detector.getCurrentSpan();
        return true;
    }

    @Override
    public void onScaleEnd(ScaleGestureDetector detector) {
        mZoomOut = detector.getCurrentSpan() - mTempSpan < 0;
        loadUrl("javascript:window.ebt.onZoom(window.innerWidth);");
    }

    public void setData(String[] clauseRelatedPath, boolean isShow) {
        mClauseXMLPath = clauseRelatedPath[2];
        String html;
        EBTFileOption option = new EBTFileOption();
        html = option.EBTReadFile(clauseRelatedPath[1], EBTGetAdviceInfo.getUid());
        if (html == null) {
            return;
        }
        String tag = "<hr color=\"#000000\" />";
        int position = html.indexOf(tag);
        if (position != -1 && ProductBridgeObj.QR.length() > 0) {

            String before = html.substring(0, position);
            String after = html.substring(position + tag.length());
            String qr = "<img src='file://" + ProductBridgeObj.QR + "' style='float:right;width: 100px;height: 100px;'>";
            html = before + tag + qr + after;
        }
        if (isShow) {
            if (mExplainList == null) {
                mExplainList = ExplainContent.get(clauseRelatedPath[2]);
            }
            for (ExplainContent content : mExplainList) {
                html = html.replaceAll(content.Name, "<b style='background:#ffff96;'><span class='explain'>" + content.Name + "</span></b>");
            }
            html = html.replaceAll("</html>", "<script type='text/javascript'>" + getResources().getString(R.string.wiki_clause_js) + "</script> </html>");
        }
        addJavascriptInterface(this, "ebt");
        html = html.replaceAll("<title>",
                "<meta name=\"viewport\" content=\"width=device-width,initial-scale=1.0,minimum-scale=1.0,maximum-scale=3.0,user-scalable=no,target-densitydpi=medium-dpi\"/>" + "<title>");
        if (!html.contains("autoexplain")) {
            html = html.replaceAll("</head>",
                    "<link href=\"../css/autoexplain.css\" rel=\"stylesheet\" /><script src=\"../js/autoexplain.js\" type=\"text/javascript\"></script></head>");
        }
        html = html.replaceAll("../tiaokuan.css", "file://" + ConfigData.PATH_RESOURCES + "theme.css");
        html = html.replaceAll("../css/autoexplain.css", "file://" + ConfigData.PATH_RESOURCES + "autoexplain.css");
        html = html.replaceAll("../js/autoexplain.js", "file://" + ConfigData.PATH_RESOURCES + "autoexplain.js");

        loadDataWithBaseURL(null, html, "text/html", "utf-8", null);
    }

    @SuppressLint("SetJavaScriptEnabled")
    private void initSettings() {
        WebSettings settings = getSettings();
        settings.setSupportZoom(false);
        settings.setBuiltInZoomControls(false); // 显示放大缩小 controler
        settings.setDefaultTextEncodingName("UTF-8");// 设置字符集编码
        settings.setDisplayZoomControls(false);
        settings.setJavaScriptEnabled(true);// 开启JavaScript支持
        setScrollBarStyle(WebView.SCROLLBARS_INSIDE_INSET);
        settings.setLoadWithOverviewMode(true);
        settings.setUseWideViewPort(false);
//		setLayerType(View.LAYER_TYPE_SOFTWARE, null);
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
            settings.setLayoutAlgorithm(WebSettings.LayoutAlgorithm.TEXT_AUTOSIZING);
        } else {
            settings.setLayoutAlgorithm(WebSettings.LayoutAlgorithm.NORMAL);
        }

    }


    /**
     * @param name        需要解释的名词
     * @param t
     * @param l
     * @param innerWidth
     * @param innerHeight
     * @param width
     * @param height
     */
    @JavascriptInterface
    public void onShow(String name, float t, float l, int innerWidth, int innerHeight, float width, float height) {
        String description = null;
        for (ExplainContent content : mExplainList) {
            if (name.equals(content.Name)) {
                description = content.Description;
                break;
            }
        }
        Context context = getContext();
        if (mPopupWindow == null) {
            View contentView = inflate(context, R.layout.wiki_window_description, null);
            mTextView = (TextView) contentView.findViewById(R.id.wiki_description);
            mPopupWindow = new PopupWindow(contentView, LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT, true);
            mPopupWindow.setBackgroundDrawable(new ColorDrawable());
            mPopupWindow.setOutsideTouchable(true);
        }
        SpannableString ss = new SpannableString(name + "：" + description.trim());
        ss.setSpan(new UnderlineSpan(), 0, name.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
        ss.setSpan(new AbsoluteSizeSpan(22, true), 0, name.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
        ss.setSpan(new StyleSpan(Typeface.BOLD), 0, name.length(), Spannable.SPAN_INCLUSIVE_EXCLUSIVE);
        mTextView.setText(ss);

        // 按照TextView的宽度为500dp、高度200dp进行适配 位置
        Log.i("EBT", "t:" + t + " l:" + l + " width:" + width + " height:" + height);
        int[] location = new int[2];
        getPopupLocation(location, t, l, innerWidth, innerHeight, height);
        mPopupWindow.showAtLocation(this, Gravity.NO_GRAVITY, location[0], location[1]);
    }

    @JavascriptInterface
    public void toHash(String anchor) {
        loadUrl("javascript:document.location.hash='" + anchor + "'");
    }

    /**
     * 缩放
     *
     * @param innerWidth
     */
    public void onZoom(int innerWidth) {
        int realWidth = UIHelper.px2dip(getContext(), getWidth());
        Log.i(TAG, "realWidth:" + realWidth + " innerWidth:" + innerWidth);
        if (mZoomOut && innerWidth == realWidth) {
            if (mListener != null) {
                mListener.onDetected(OnGestureListener.EXIT);
            }
        }
    }

    /**
     * 按照TextView的宽度为500dp、高度200dp进行适配 位置 //FIXME 待优化
     *
     * @param location
     * @param top
     * @param left
     */
    private void getPopupLocation(int[] location, float top, float left, int innerWidth, int innerHeight, float height) {
        left = Math.abs(left);// px
        top = Math.abs(top);// px
        int[] axis = new int[2];// px
        getLocationOnScreen(axis);
        int x = axis[0];
        int y = axis[1];
        int viewWidth = getWidth();// px
        int viewHeight = getHeight();

        top = top * viewHeight / innerHeight;
        left = left * viewWidth / innerWidth;

        location[0] = (int) left;
        location[1] = (int) (top - height - UIHelper.dip2px(getContext(), 10));
        // 10是阴影部分 dp
        if (left < x) {
            Log.i(TAG, "left...");
            location[0] = (int) (x + left / 2);
        } else if (x + viewWidth < left + UIHelper.dip2px(getContext(), 510)) {
            Log.i(TAG, "right...");
            location[0] = (int) (x + viewWidth - UIHelper.dip2px(getContext(), 500));
        }
        if (top < UIHelper.dip2px(getContext(), 200)) {
            Log.i(TAG, "bottom...");
            location[1] = (int) (y + top + height);
        }
        Log.i(TAG, "x:" + x + " y:" + y + " top:" + top + " left:" + left + " height:" + height + " viewWidth:" + viewWidth + " getRight:" + getRight());
    }


    public interface OnGestureListener {
        public static final int DOUBLETAP = 0;
        public static final int EXIT = 1;

        /**
         * 检测到手势
         *
         * @param event
         */
        void onDetected(int event);

        public void onLongPress();
    }

    private OnGestureListener mListener;

    public void setOnGestureListener(OnGestureListener l) {
        mListener = l;
    }

    @JavascriptInterface
    public String getExplainItem(String brandId, String categoryId, String itemId) {
        Logger.e("brandId=" + brandId + ";categoryId=" + categoryId + ";itemId=" + itemId);
        String jsonResult = null;
        String path = mClauseXMLPath;
        File file = new File(path);
        if (!file.exists()) {
            return null;
        }

        DocumentBuilderFactory factory = null;
        DocumentBuilder builder = null;
        Document document = null;
        InputStream inputStream = null;
        factory = DocumentBuilderFactory.newInstance();
        try {
            builder = factory.newDocumentBuilder();
            inputStream = new FileInputStream(path);
            document = builder.parse(inputStream);
            Element root = document.getDocumentElement();
            NodeList brandNodes = root.getElementsByTagName("brand");
            for (int i = 0; i < brandNodes.getLength(); i++) {
                Element brandElement = (Element) (brandNodes.item(i));
//                String sBrandId = brandElement.getAttribute("id");
//                if (sBrandId.equals(brandId)) {
                NodeList categoryNodes = brandElement.getElementsByTagName("category");
                for (int j = 0; j < categoryNodes.getLength(); j++) {
                    Element categroyElement = (Element) (categoryNodes.item(j));
                    String sCategory = categroyElement.getAttribute("id");
                    if (sCategory.equals(categoryId)) {
                        NodeList itemNodes = categroyElement.getElementsByTagName("item");
                        for (int k = 0; k < itemNodes.getLength(); k++) {
                            Element itemElement = (Element) (itemNodes.item(k));
                            String sItemId = itemElement.getAttribute("id");
                            if (sItemId.equals(itemId)) {
                                JSONObject contentJson = new JSONObject();
                                try {
                                    contentJson.put("explain", itemElement.getTextContent().replace("\n", "<br/>"));
                                    contentJson.put("name", itemElement.getAttribute("name"));
                                    contentJson.put("value", itemElement.getAttribute("value"));
                                    contentJson.put("refName", itemElement.getAttribute("refName"));
                                    contentJson.put("refLink", itemElement.getAttribute("refLink"));
//                                        contentJson.put("refImg", itemElement.getAttribute("refImg"));
                                    contentJson.put("refImg", getImgUrl(itemElement));
                                } catch (DOMException e) {
                                    Log.i(TAG, e.toString());
                                } catch (JSONException e) {
                                    Log.i(TAG, e.toString());
                                }
                                jsonResult = contentJson.toString();
                                break;
                            }
                        }
                        break;
                    }
                }
                break;
            }
//            }
            Log.i(TAG, "success parsed");
        } catch (IOException e) {
            e.printStackTrace();
        } catch (SAXException e) {
            e.printStackTrace();
        } catch (ParserConfigurationException e) {
            e.printStackTrace();
        } finally {
            try {
                if (inputStream != null) {
                    inputStream.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        return jsonResult;
    }

    /**
     * 名词解释的文字 优先本地的；图片如果在线，就联网加载，如果不在线，就取本地的默认
     *
     * @param itemElement
     * @return
     */
    public String getImgUrl(Element itemElement) {
        String url = "";
        try {
            if (NetUtils.isNetworkConnected(getContext())) {
                url = itemElement.getAttribute("refImg");
            } else {
                url = "file:///" + ConfigData.PORTRAITPATH + "/icon_none.png";
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

        return url;
    }
}
